package com.chengxiaoxiao.ai_demo.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chengxiaoxiao.ai_demo.config.FileProperties;
import com.chengxiaoxiao.ai_demo.entity.KnowledgeFile;
import com.chengxiaoxiao.ai_demo.mapper.KnowledgeFileMapper;
import com.chengxiaoxiao.ai_demo.service.DocumentEmbeddingService;
import com.chengxiaoxiao.ai_demo.service.KnowledgeFileService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


/**
 * knowledgeInfo 服务实现类
 *
 * @Description:
 * @Author: Cheng Xiaoxiao
 * @Date: 2025-03-14 16:50:21
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class KnowledgeFileServiceImpl extends ServiceImpl<KnowledgeFileMapper, KnowledgeFile> implements KnowledgeFileService {
    final FileProperties fileProperties;
    final DocumentEmbeddingService documentEmbeddingService;

    /**
     * 获取knowledgeInfo详情
     *
     * @param id ID
     * @return 单个knowledgeInfo详情
     */
    @Override
    public KnowledgeFile detailById(String id) {
        return getById(id);
    }

    /**
     * 增加knowledgeInfo
     *
     * @param knowledgeFile knowledgeInfo对象
     * @return 增加后的数据
     */
    @Override
    public KnowledgeFile saveKnowledgeInfo(KnowledgeFile knowledgeFile) {
        this.baseMapper.insert(knowledgeFile);
        return knowledgeFile;
    }

    /**
     * 修改knowledgeInfo
     *
     * @param knowledgeFile knowledgeInfo对象
     * @return 修改后的数据
     */
    @Override
    public KnowledgeFile updateKnowledgeInfoById(KnowledgeFile knowledgeFile) {
        this.baseMapper.updateById(knowledgeFile);
        return knowledgeFile;
    }

    /**
     * 根据ID删除
     *
     * @param id ID
     */
    @Override
    public void deleteById(String id) {
        removeById(id);
    }

    /**
     * 对指定的知识库批量添加文件
     *
     * @param knowledgeBaseId 知识库ID
     * @param multipartFiles  文件集合
     */
    @Override
    public void batchAddFiles(String knowledgeBaseId, List<MultipartFile> multipartFiles) {
        List<KnowledgeFile> knowledgeFiles = new ArrayList<>();
        for (MultipartFile multipartFile : multipartFiles) {
            KnowledgeFile knowledgeFile = new KnowledgeFile();
            knowledgeFile.setKnowledgeBaseId(knowledgeBaseId);
            knowledgeFile.setFileName(multipartFile.getOriginalFilename());
            knowledgeFile.setIsEnabled(true);
            knowledgeFile.setStorePath(saveFile2FileSystem(knowledgeBaseId, multipartFile));
            knowledgeFiles.add(knowledgeFile);
        }
        saveBatch(knowledgeFiles);
        log.info("知识库{}添加文件成功", knowledgeBaseId);

        //进行调用调入模型进行嵌入
        documentEmbeddingService.embeddingDocument(knowledgeBaseId, knowledgeFiles);
    }

    /**
     * 存储文件并返回相对路径
     *
     * @param knowledgeBaseId 所属知识库
     * @param multipartFile   文件
     * @return 相对路径
     */
    private String saveFile2FileSystem(String knowledgeBaseId, MultipartFile multipartFile) {
        try {
            String originalFilename = multipartFile.getOriginalFilename();
            String dir = fileProperties.getSavePath() + knowledgeBaseId;
            String fileName = FileNameUtil.mainName(originalFilename) + StrUtil.UNDERLINE + IdUtil.getSnowflake().nextIdStr() + StrUtil.DOT + FileNameUtil.extName(originalFilename);
            String filePath = dir + StrUtil.C_SLASH + fileName;

            //如果文件夹不存在，创建
            if (!FileUtil.exist(dir)) {
                FileUtil.mkdir(dir);
            }
            // 保存文件
            multipartFile.transferTo(new File(filePath));
            return knowledgeBaseId + StrUtil.C_SLASH + fileName;
        } catch (IOException e) {
            e.printStackTrace();
            log.error("文件存储失败：文件名{}", multipartFile.getOriginalFilename());
        }
        return null;
    }

    /**
     * 根据知识库ID删除知识库文件
     *
     * @param knowledgeBaseId 知识库ID
     */
    @Override
    public void deleteByKnowledgeBaseId(String knowledgeBaseId) {
        baseMapper.delete(new LambdaQueryWrapper<KnowledgeFile>().eq(KnowledgeFile::getKnowledgeBaseId, knowledgeBaseId));

        //删除嵌入信息
        documentEmbeddingService.deleteByKnowledgeBaseId(knowledgeBaseId);
    }
}